/*=========================================================================

Program:   Virtual Surgery
Language:  C++
Date:      2009-9-1
Version:   0.1
Mail:		   nelfylee@gmail.com

Copyright (c) 2009 Nelfy Lee. All rights reserved.

=========================================================================*/
#include "Source.h"
#include "PipelineModel.h"


#include "vtkCone.h"
#include "vtkPolyDataConnectivityFilter.h"
#include "vtkFixedPointVolumeRayCastMapper.h"
#include "vtkSelectEnclosedPoints.h"
#include "vtkWindowedSincPolyDataFilter.h"
#include "vtkClipPolyData.h"

#include <QStandardItem>
#include <QPolygonF>




Source::Source(const QString &text):QStandardItem(text)
{
	m_sourceText=text;
	m_vtkImage=NULL;
	m_dataType=VTK_VOID;
	m_pipelineModel=NULL;
	g_colorTable = new QList<QColor>();
	g_colorTable->push_back(QColor::fromRgb(255, 0, 0));
	g_colorTable->push_back(QColor::fromRgb(0, 0, 255));
	g_colorTable->push_back(QColor::fromRgb(170, 85, 255));
	g_colorTable->push_back(QColor::fromRgb(170, 170, 255));
	g_colorTable->push_back(QColor::fromRgb(170, 170, 0));
	g_colorTable->push_back(QColor::fromRgb(255, 85, 255));
	g_colorTable->push_back(QColor::fromRgb(85, 170, 255));
	g_colorTable->push_back(QColor::fromRgb(85, 85, 255));
	g_colorTable->push_back(QColor::fromRgb(255, 170, 0));
	g_colorTable->push_back(QColor::fromRgb(255, 0, 127));

	initModelParameters();
}

Source::~Source()
{
	if (m_vtkImage)
		m_vtkImage->Delete();
}


void Source::initModelParameters()
{
	m_outlineActor=NULL;
	m_outlinePolyDataMapper=NULL;
	m_outlineFilter=NULL;
}


void Source::addChild(Source *source)
{
	source->m_pipelineModel = this->m_pipelineModel;

	appendRow(source);

	m_pipelineModel->sourceAdded(source);
}


int Source::dim()
{
	if ( m_vtkImage)
	{
		return m_vtkImage->GetDataDimension();
	}

	return 0;
}



QString Source::fileName() 
{ 
	return m_fileName;
}

void Source::setFileName(QString fileName) 
{ 
	m_fileName = fileName;
}

vtkImageData * Source::data() 
{ 
	return m_vtkImage;
}

SourceType Source::type()
{
	return m_type;
}


int Source::dataType()
{
	return m_dataType;
}

void Source::emitPropertyChanged(SourceProperty sp)
{
	m_pipelineModel->propertyChanged(this, sp);
}


vtkActor* Source::outlineActor()
{
	if ( !m_vtkImage)
		return NULL;

	if ( m_outlineActor)
		return m_outlineActor;

	m_outlineFilter = vtkOutlineFilter::New();
	m_outlineFilter->SetInput(m_vtkImage);

	m_outlinePolyDataMapper = vtkPolyDataMapper::New();
	m_outlinePolyDataMapper->SetInputConnection(m_outlineFilter->GetOutputPort());

	m_outlineActor = vtkActor::New();
	m_outlineActor->SetMapper(m_outlinePolyDataMapper);

	return m_outlineActor;
}


void Source::clearOutlineActor()
{
	if ( !m_outlineActor)
		return;

	m_outlineActor->Delete(); m_outlineActor=NULL;
	m_outlinePolyDataMapper->Delete(); m_outlinePolyDataMapper=NULL;
	m_outlineFilter->Delete(); m_outlineFilter=NULL;
}


QStringList Source::childrenList()
{
	QStringList subsources;

	for ( int i = 0; i < rowCount(); i++)
	{
		subsources << child(i)->text();
	}

	return subsources;
}
// 
// vtkProp* Source::sourceModel( bool refresh/*=false*/ )
// {
// 	return m_sourceModel;
// }

void Source::clearModel()
{

}


// vtkContourFilter*
// Source::getSurfaceData()
// {
// 	return m_smContour;
// }
// 


// 
// vtkActor* 
// Source::getSurfaceModel(bool reset /* = false*/)
// {
// 	if ( !m_vtkImage)
// 		return NULL;
// 
// 	if ( m_smActor && !reset)
// 		return m_smActor;
// 
// 	double range[2];
// 	m_vtkImage->GetScalarRange(range);
// 
// 	m_smContour = vtkContourFilter::New();
// 	m_smContour->SetInput(m_vtkImage);
// 	m_smContour->SetValue(0,(range[0]+range[1])/2.0);
// 	//m_smContour->ComputeScalarsOn();
// 	//m_smContour->ComputeNormalsOn();
// 
// 
// // 	vtkWindowedSincPolyDataFilter *smooth = vtkWindowedSincPolyDataFilter::New();
// // 
// // 	smooth->SetInput(m_smContour->GetOutput());
// // 	smooth->SetNumberOfIterations(10);
// // 	smooth->BoundarySmoothingOn();
// // 	smooth->SetFeatureAngle(120);
// // 	smooth->SetEdgeAngle(90);
// // 	smooth->SetPassBand (0.1);
// // 
// // 
// // 	m_smNormals = vtkPolyDataNormals::New();
// // 	m_smNormals->SetInputConnection(smooth->GetOutputPort());
// // // 	m_smNormals->SetFeatureAngle(60.0);
// 
// // 
// // 	vtkPolyDataConnectivityFilter *smConnectivity = vtkPolyDataConnectivityFilter::New();
// // 
// // 	smConnectivity->SetInputConnection(m_smContour->GetOutputPort());
// // 	smConnectivity->SetExtractionModeToLargestRegion();
// // 	smConnectivity->SetScalarRange(range[0], range[1]);
// 
// 
// // 	vtkSelectEnclosedPoints *select = vtkSelectEnclosedPoints::New();
// // 	select->SetInput(m_vtkImage);
// // 	select->SetSurfaceConnection(m_smContour->GetOutputPort());
// 
// 
// 	m_smPolyDataMapper = vtkPolyDataMapper::New();
// 	m_smPolyDataMapper->SetInputConnection(m_smContour->GetOutputPort());
// 	m_smPolyDataMapper->ScalarVisibilityOff();
// 
// 	m_smActor = vtkActor::New();
// 	m_smActor->SetMapper(m_smPolyDataMapper);
// 	m_smActor->PickableOn();
// 	
// 	return m_smActor;
// }

// void 
// Source::clearSurfaceModel()
// {
// 	if ( !m_smActor)
// 		return;
// 
// 	m_smActor->Delete(); m_smActor=NULL;
// 	m_smPolyDataMapper->Delete(); m_smPolyDataMapper=NULL;
// 	m_smContour->Delete(); m_smContour=NULL;
// }
// 


// 
// vtkVolume* 
// Source::getVolumeModel()
// {
// 	if ( !m_vtkImage)
// 		return NULL;
// 
// 	if ( m_vmVolume)
// 		return m_vmVolume;
// 
// 	m_vmImageCast = vtkImageCast::New();
// 	m_vmImageCast->SetInput(m_vtkImage);
// 	m_vmImageCast->SetOutputScalarTypeToUnsignedChar();
// 
// 	m_vmOpacityTransferFunction = vtkPiecewiseFunction::New();
// 	m_vmColorTransferFunction = vtkColorTransferFunction::New();
// 
// 	if ( m_upperThreshold == 1.0 && m_lowerThreshold == 0)
// 	{
// 		m_vmOpacityTransferFunction->AddPoint(m_lowerThreshold, 0);
// 		m_vmOpacityTransferFunction->AddPoint(m_upperThreshold, 0.2);
// 
// 		m_vmColorTransferFunction->AddRGBPoint(m_lowerThreshold, 0.0, 0.0, 0.0);
// 		m_vmColorTransferFunction->AddRGBPoint(m_upperThreshold, 1.0, 97.0/255.0, 0);
// 	}
// 	else
// 	{
// // 		m_vmOpacityTransferFunction->AddPoint(m_lowerThreshold, 0);
// // 		m_vmOpacityTransferFunction->AddPoint(m_lowerThreshold/2.0, 0.1);
// // 		m_vmOpacityTransferFunction->AddPoint(m_lowerThreshold/2.0 + m_upperThreshold/2.0, 0.2);
// // 		m_vmOpacityTransferFunction->AddPoint(m_upperThreshold/2.0, 0.2);
// // 		m_vmOpacityTransferFunction->AddPoint(m_upperThreshold, 1);
// 
// 		m_vmOpacityTransferFunction->AddSegment(100,0.0, 255, 1);
// 
// 		m_vmColorTransferFunction->AddRGBPoint(0, 1.0, 0.0, 0.0);
// 		m_vmColorTransferFunction->AddRGBPoint(64, 1.0, 1.0, 0.0);
// 		m_vmColorTransferFunction->AddRGBPoint(128, 0.0, 1.0, 0.0);
// 		m_vmColorTransferFunction->AddRGBPoint(192, 0.0, 1.0, 1.0);
// 		m_vmColorTransferFunction->AddRGBPoint(255, 0.0, 0.0, 1.0);
// 	}
// 
// 	m_vmVolumeProperty = vtkVolumeProperty::New();
// 	m_vmVolumeProperty->SetColor(m_vmColorTransferFunction);
// 	m_vmVolumeProperty->SetScalarOpacity(m_vmOpacityTransferFunction);
// 	m_vmVolumeProperty->SetShade(0);
// // 	m_vmVolumeProperty->SetAmbient(0.3);
// // 	m_vmVolumeProperty->SetDiffuse(1.0);
// // 	m_vmVolumeProperty->SetSpecular(0.2);
// 	m_vmVolumeProperty->SetInterpolationTypeToLinear();
// 
// 
// // 	m_vmVolumeRayCastCompositeFunction = vtkVolumeRayCastCompositeFunction::New();
// // 
// // 	m_vmVolumeRayCastMapper = vtkVolumeRayCastMapper::New();
// // 	m_vmVolumeRayCastMapper->SetVolumeRayCastFunction(m_vmVolumeRayCastCompositeFunction);
// // 	m_vmVolumeRayCastMapper->SetInputConnection(m_vmImageCast->GetOutputPort());
// // 	m_vmVolumeRayCastMapper->Update();
// 
// 	vtkFixedPointVolumeRayCastMapper *mapper = vtkFixedPointVolumeRayCastMapper::New();
// 	mapper->SetBlendModeToMaximumIntensity();
// 	mapper->SetInputConnection( m_vmImageCast->GetOutputPort() );
// 
// 	m_vmVolume = vtkVolume::New();
// 	m_vmVolume->SetMapper(mapper);
// 	m_vmVolume->SetProperty(m_vmVolumeProperty);
// 
// 	return m_vmVolume;
// }


// void 
// Source::clearVolumeModel()
// {
// 	if (!m_vmVolume)
// 		return;
// 
// 	m_vmImageCast->Delete(); m_vmImageCast=NULL;
// 	m_vmOpacityTransferFunction->Delete(); m_vmOpacityTransferFunction=NULL;
// 	m_vmColorTransferFunction->Delete(); m_vmColorTransferFunction=NULL;
// 	m_vmVolumeProperty->Delete(); m_vmVolumeProperty=NULL;
// 	//m_vmVolumeRayCastCompositeFunction->Delete(); m_vmVolumeRayCastCompositeFunction=NULL;
// 	//m_vmVolumeRayCastMapper->Delete(); m_vmVolumeRayCastMapper=NULL;
// 	m_vmVolume->Delete(); m_vmVolume=NULL;
// } 



// Source* Source::child(QString name)
// {
// 	for ( int i = 0; i < rowCount(); i++)
// 	{
// 		if (child(i)->text() == name)
// 			return (Source*)child(i);
// 	}
// 	
// 	return NULL;
// }

/*
bool Source::isModeling()
{
	return m_modeling;
}*/
